package com.party.web.web.controller.crowdfund;

import com.party.common.constant.Constant;
import com.party.common.paging.Page;
import com.party.common.utils.StringUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.activity.Activity;
import com.party.core.model.crowdfund.*;
import com.party.core.model.distributor.DistributorRelation;
import com.party.core.model.log.BehaviorType;
import com.party.core.model.member.Member;
import com.party.core.model.order.RefundPlan;
import com.party.core.model.wechat.WechatMerchants;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.crowdfund.*;
import com.party.core.service.distributor.IDistributorRelationService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.order.IOrderFormService;
import com.party.core.service.order.IRefundPlanService;
import com.party.core.service.wechat.IWechatMerchantsService;
import com.party.web.biz.activity.ActivityBizService;
import com.party.web.biz.crowdfund.ProjectBizService;
import com.party.web.biz.crowdfund.SupportBizService;
import com.party.web.biz.crowdfund.TargetBizService;
import com.party.web.biz.file.ExcelExportService;
import com.party.web.utils.excel.ExportExcel;
import com.party.web.web.annotation.ControlParam;
import com.party.web.web.annotation.DataControl;
import com.party.web.web.annotation.UserOperate;
import com.party.web.web.dto.AjaxResult;
import com.party.web.web.dto.output.crowdfund.SupportCountOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * Created by wei.li
 *
 * @date 2017/3/28 0028
 * @time 16:13
 */
@SuppressWarnings("all")
@Controller
@RequestMapping(value = "crowdfund/support")
public class SupportController {

    @Autowired
    private SupportBizService supportBizService;

    @Autowired
    private IActivityService activityService;

    @Autowired
    private IOrderFormService orderFormService;

    @Autowired
    private ActivityBizService activityBizService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private IMemberService memberService;

    @Autowired
    private IDistributorRelationService distributorRelationService;

    @Autowired
    private ExcelExportService excelExportService;

    @Autowired
    private ICrowdfundEventService crowdfundEventService;

    @Autowired
    private IWechatMerchantsService wechatMerchantsService;

    @Autowired
    private ISupportService supportService;

    @Autowired
    private ProjectBizService projectBizService;

    @Autowired
    private ISupportTransferService supportTransferService;

    @Autowired
    private TargetBizService targetBizService;

    @Autowired
    private ITargetProjectService targetProjectService;
    @Autowired
    private IRefundPlanService refundPlanService;


    protected Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 根据分销关系编号查询支持列表
     * @param id 活动编号
     * @param relationId 分销关系
     * @param page 分页参数
     * @return
     */
    @DataControl
    @RequestMapping(value = "listForDistributorId")
    public ModelAndView listForDistributorId(@ControlParam(table = "activity", column = "member", isDistribution = true) String relationId, String merchantId, Page page){
        ModelAndView modelAndView = new ModelAndView("activity/supportList");
        modelAndView.addObject("isMultiple", false);
        modelAndView.addAllObjects(supportBizService.listForDistributorCommonActivity(relationId, merchantId, page));
        return modelAndView;
    }


    /**
     * 根据分销关系编号查询支持列表导出
     * @param relationId 分销关系
     * @param name 联合发起名称
     * @param response 响应参数
     * @return
     */
    @DataControl
    @ResponseBody
    @RequestMapping(value = "listForDistributorIdExport")
    public AjaxResult listForDistributorIdExport(@ControlParam(table = "activity", column = "member", isDistribution = true) String relationId, String name, String merchantId) {
        String fileName = name + "联合发起的支持人.xlsx";
        List<SupportWithMember> supportWithMemberList = supportBizService.listForDistributorId(relationId, merchantId,null);
        try {
            ExportExcel exportExcel = new ExportExcel(fileName, SupportWithMember.class).setDataList(supportWithMemberList);
            String allPath = excelExportService.getExcelPath(fileName, "represent/support", exportExcel);
            return AjaxResult.success((Object)allPath);
        } catch (IOException e) {
            logger.error("导出支持人异常", e);
        }
        return AjaxResult.error("导出异常");
    }


    /**
     * 根据分销关系编号查询支持列表
     * @param relationId 分销关系
     * @param page 分页参数
     * @return
     */
    @DataControl
    @RequestMapping(value = "event/listForDistributorId")
    public ModelAndView listEventForDistributorId(@ControlParam(table = "zc_event", column = "create_by") String eventId,
                                                  @ControlParam(table = "activity", column = "member", isDistribution = true) String relationId, String merchantId, Page page){
        ModelAndView modelAndView = new ModelAndView("crowdfund/supportList");
        Integer directPayNum = projectService.dpCountForEvent(eventId,null);
        modelAndView.addObject("isMultiple", false);
        modelAndView.addAllObjects(supportBizService.listForDistributorCommonEvent(eventId, relationId, merchantId, page));
        return modelAndView;
    }


    /**
     * 根据分销关系编号查询支持列表导出
     * @param relationId 分销关系
     * @param response 响应参数
     * @return
     */
    @DataControl
    @ResponseBody
    @RequestMapping(value = "event/listForDistributorIdExport")
    public AjaxResult listEventForDistributorIdExport(@ControlParam(table = "zc_event", column = "create_by") String eventId,
                                                      @ControlParam(table = "activity", column = "member", isDistribution = true) String relationId, String merchantId){
        DistributorRelation distributorRelation = distributorRelationService.get(relationId);
        Member author = memberService.get(distributorRelation.getDistributorId());
        String fileName = author.getRealname() + "联合发起的支持人.xlsx";
        List<SupportWithMember> supportWithMemberList = supportBizService.listForDistributorId(relationId, merchantId, null);
        try {
            ExportExcel exportExcel = new ExportExcel(fileName, SupportWithMember.class).setDataList(supportWithMemberList);
            String allPath = excelExportService.getExcelPath(fileName, "represent/support", exportExcel);
            return AjaxResult.success((Object)allPath);
        } catch (IOException e) {
            logger.error("导出支持人异常", e);
        }
        return AjaxResult.error("导出异常");
    }




    /**
     * 众筹项目查询支持
     * @param id 活动编号
     * @param page 分页参数
     * @return 支持列表
     */
    @DataControl
    @RequestMapping(value = "listForProjectId")
    public ModelAndView listForProjectId(@ControlParam(table = "activity", column = "member", getMethodName = "getProjectId", isProjectId = true) SupportWithMember supportWithMember, Page page, Integer source){
        ModelAndView modelAndView = new ModelAndView("activity/supportForProjectList");
        //是否可以退款
        boolean isCan = false;
        boolean isRefundPlan = false;
        try {
            isCan = projectService.isCanRefund(supportWithMember.getProjectId());
            if (isCan) {
                RefundPlan refundPlan = refundPlanService.getByGoalId(supportWithMember.getProjectId());
                if (refundPlan != null) {
                    isRefundPlan = true;
                    Integer refundFailCount = supportService.refundAllFailCount(supportWithMember.getProjectId());
                    List<Support> supportByProjectId = supportService.findSupportByProjectId(supportWithMember.getProjectId());
                    Integer status = 0;
                    for (Support support : supportByProjectId) {
                        if( 1 == support.getPayStatus()){
                            status = 1;
                            break;
                        }
                    }
                    if("0".equals(refundPlan.getStatus()) && "0".equals(refundPlan.getResult())){
                         //如果取消了退款，还是显示全部退款按钮
                    }else if (1 == status && "0".equals(refundPlan.getStatus())){
                         //如果有一个支持者的状态是支付成功状态，还是显示全部退款按钮
                    }else if (0 == refundFailCount || "1".equals(refundPlan.getStatus())) {
                        //退款失败人数为0  就不显示全部退款按钮
                        isCan = false;
                    }
                }else {
                    boolean refundAll = supportService.isRefundAll(supportWithMember.getProjectId());
                    isCan = refundAll == true ? false : true;
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        modelAndView.addObject("isRefundPlan", isRefundPlan);
        modelAndView.addObject("isCan", isCan);
        modelAndView.addObject("isMultiple", false);
        modelAndView.addAllObjects(supportBizService.listForProjectCommonActivity(supportWithMember, page, source));
        return modelAndView;
    }

    /**
     * 众筹项目查询支持
     * @param id 活动编号
     * @param page 分页参数
     * @return 支持列表
     */
    @DataControl
    @RequestMapping(value = "dpListForProjectId")
    public ModelAndView dpListForProjectId(@ControlParam(table = "activity", column = "member", getMethodName = "getProjectId", isProjectId = true) SupportWithMember supportWithMember, Page page){
        page.setLimit(20);
        ModelAndView modelAndView = new ModelAndView("activity/supportForDpProjectList");

        List<SupportWithMember> supportWithMemberList = supportService.listWithMemberAndMerchant(supportWithMember, page);

        TargetProject targetProject = targetProjectService.findByProjectId(supportWithMember.getProjectId());

        Activity activity = activityService.get(targetProject.getTargetId());

        Project project = projectService.get(supportWithMember.getProjectId());
        Member author = memberService.get(project.getAuthorId());

        modelAndView.addObject("projectId", supportWithMember.getProjectId());
        modelAndView.addObject("page", page);
        modelAndView.addObject("list", supportWithMemberList);
        modelAndView.addObject("name", author.getRealname());
        modelAndView.addObject("id", targetProject.getTargetId());
        modelAndView.addObject("startTime", supportWithMember.getStartTime());
        modelAndView.addObject("merchantId", supportWithMember.getMerchantId());
        List<WechatMerchants> wechatMerchants = wechatMerchantsService.getMerchant(activity.getMember());
        modelAndView.addObject("wechatMerchants", wechatMerchants);

        modelAndView.addAllObjects(targetBizService.getTargetData(targetProject.getTargetId()));
        return modelAndView;
    }

    /**
     * 导出众筹项目的支持
     * @param projectId 项目编号
     * @param name 项目名称
     * @param response 响应参数
     * @return
     */
    @DataControl
    @ResponseBody
    @RequestMapping(value = "listForProjectIdExport")
    public AjaxResult listForProjectIdExport(@ControlParam(table = "activity", column = "member", isProjectId = true)
                                                         SupportWithMember supportWithMember, String name, HttpServletResponse response){
        String fileName = name + "的众筹的支持人.xlsx";
        List<SupportWithMember> supportWithMemberList = supportService.listWithMemberAndMerchant(supportWithMember, null);
        try {
            ExportExcel exportExcel = new ExportExcel(fileName, SupportWithMember.class).setDataList(supportWithMemberList);
            String allPath = excelExportService.getExcelPath(fileName, "crowdfund/support", exportExcel);
            return AjaxResult.success((Object)allPath);
        } catch (IOException e) {
            logger.error("导出支持人异常", e);
        }
        return AjaxResult.error("导出异常");
    }

    @DataControl
    @RequestMapping(value = "event/listForProjectId")
    public ModelAndView listEventForProjectId(@ControlParam(table = "zc_event", column = "create_by") String eventId,
                                              @ControlParam(table = "activity", column = "member", isProjectId = true) String projectId,
                                              String merchantId, String startTime, Page page) {
        ModelAndView modelAndView = new ModelAndView("crowdfund/supportForProjectList");
        SupportWithMember supportWithMember = new SupportWithMember();
        supportWithMember.setMerchantId(merchantId);
        supportWithMember.setProjectId(projectId);
        modelAndView.addAllObjects(supportBizService.listForProjectCommonEvent(page, eventId, supportWithMember, startTime));
        modelAndView.addObject("isMultiple", false);
        return modelAndView;
    }

    @DataControl
    @RequestMapping(value = "event/dpListForProjectId")
    public ModelAndView dpListForProjectId(@ControlParam(table = "zc_event", column = "create_by") String eventId,
                                           @ControlParam(table = "activity", column = "member", isProjectId = true) String projectId, String merchantId, String startTime, Page page){
        page.setLimit(20);
        ModelAndView modelAndView = new ModelAndView("crowdfund/supportForDpProjectList");
        List<SupportWithMember> supportWithMemberList = supportBizService.listForProjectId(projectId, startTime, merchantId, page);

        Integer representNum = distributorRelationService.countForEvent(eventId);
        Integer projectNum = projectService.countForEvent(eventId);
        Integer directPayNum = projectService.dpCountForEvent(eventId,null);

        Project project = projectService.get(projectId);
        Member author = memberService.get(project.getAuthorId());

        modelAndView.addObject("representNum", representNum);
        modelAndView.addObject("projectNum", projectNum);
        modelAndView.addObject("directPayNum", directPayNum);
        modelAndView.addObject("projectId", projectId);
        modelAndView.addObject("eventId", eventId);
        modelAndView.addObject("page", page);
        modelAndView.addObject("list", supportWithMemberList);
        modelAndView.addObject("name", author.getRealname());
        modelAndView.addObject("startTime", startTime);
        CrowdfundEvent crowdfundEvent = crowdfundEventService.get(eventId);
        modelAndView.addObject("crowdfundEvent", crowdfundEvent);
        modelAndView.addObject("merchantId", merchantId);
        List<WechatMerchants> wechatMerchants = wechatMerchantsService.getMerchant(crowdfundEvent.getCreateBy());
        modelAndView.addObject("wechatMerchants", wechatMerchants);
        return modelAndView;
    }


    /**
     * 导出众筹项目的支持
     * @param projectId 项目编号
     * @param response 响应参数
     * @return
     */
    @DataControl
    @ResponseBody
    @RequestMapping(value = "event/listForProjectIdExport")
    public AjaxResult listEventForProjectIdExport(@ControlParam(table = "zc_event", column = "create_by") String eventId,
                                                  @ControlParam(table = "activity", column = "member", isProjectId = true) String projectId, String merchantId, HttpServletResponse response){
        Project project = projectService.get(projectId);
        Member author = memberService.get(project.getAuthorId());
        String fileName = author.getRealname() + "的众筹的支持人.xlsx";
        List<SupportWithMember> supportWithMemberList = supportBizService.listForProjectId(projectId, null, merchantId,null);
        try {
            ExportExcel exportExcel = new ExportExcel(fileName, SupportWithMember.class).setDataList(supportWithMemberList);
            String allPath = excelExportService.getExcelPath(fileName, "crowdfund/support", exportExcel);
            return AjaxResult.success((Object)allPath);
        } catch (IOException e) {
            logger.error("导出支持人异常", e);
        }
        return AjaxResult.error("导出异常");
    }

    /**
     * 众筹项目查询支持
     * @param id 活动编号
     * @param page 分页参数
     * @return 支持列表
     */
    @DataControl
    @RequestMapping(value = "listForRepresent")
    public ModelAndView listForRepresent(@ControlParam(table = "activity", column = "member", isProjectId = true, getMethodName = "getProjectId") SupportWithMember supportWithMember, Page page) {
        ModelAndView modelAndView = new ModelAndView("activity/supportForRepresentList");
        //是否可以退款
        boolean isCan = false;
        boolean isRefundPlan = false;
        try {
            isCan = projectService.isCanRefund(supportWithMember.getProjectId());
            if (isCan) {
                RefundPlan refundPlan = refundPlanService.getByGoalId(supportWithMember.getProjectId());
                if (refundPlan != null) {
                    isRefundPlan = true;
                    Integer refundFailCount = supportService.refundAllFailCount(supportWithMember.getProjectId());
                    List<Support> supportByProjectId = supportService.findSupportByProjectId(supportWithMember.getProjectId());
                    Integer status = 0;
                    for (Support support : supportByProjectId) {
                        if( 1 == support.getPayStatus()){
                            status = 1;
                            break;
                        }
                    }
                    if("0".equals(refundPlan.getStatus()) && "0".equals(refundPlan.getResult())){
                        //如果取消了退款，还是显示全部退款按钮
                    }else if (1 == status && "0".equals(refundPlan.getStatus())){
                        //如果有一个支持者的状态是支付成功状态，还是显示全部退款按钮
                    }else if (0 == refundFailCount || "1".equals(refundPlan.getStatus())) {
                        //退款失败人数为0  就不显示全部退款按钮
                        isCan = false;
                    }
                }else {
                    boolean refundAll = supportService.isRefundAll(supportWithMember.getProjectId());
                    isCan = refundAll == true ? false : true;
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        modelAndView.addObject("isRefundPlan", isRefundPlan);
        modelAndView.addObject("isCan", isCan);
        modelAndView.addObject("isMultiple", false);
        modelAndView.addAllObjects(supportBizService.listForRepresentCommonActivity(page, supportWithMember));
        return modelAndView;
    }

    /**
     * 导出众筹项目的支持
     * @param projectId 项目编号
     * @param name 项目名称
     * @param response 响应参数
     * @return
     */
    @DataControl
    @ResponseBody
    @RequestMapping(value = "listForRepresentExport")
    public AjaxResult listForRepresentExport(@ControlParam(table = "activity", column = "member", isProjectId = true) String projectId, String name, String merchantId, HttpServletResponse response){
        String fileName = name + "的众筹的支持人.xlsx";
        List<SupportWithMember> supportWithMemberList = supportBizService.listForProjectId(projectId, null, merchantId,null);
        try {
            ExportExcel exportExcel = new ExportExcel(fileName, SupportWithMember.class).setDataList(supportWithMemberList);
            String allPath = excelExportService.getExcelPath(fileName, "crowdfund/support", exportExcel);
            return AjaxResult.success((Object)allPath);
        } catch (IOException e) {
            logger.error("导出支持人异常", e);
        }
        return AjaxResult.error("导出异常");
    }


    /**
     * 众筹项目查询支持
     * @param projectId 众筹编号
     * @param page 分页参数
     * @return 支持列表
     */
    @DataControl
    @RequestMapping(value = "event/listForRepresent")
    public ModelAndView listEventForRepresent(@ControlParam(table = "zc_event", column = "create_by") String eventId,
                                              @ControlParam(table = "activity", column = "member", isProjectId = true) String projectId, String merchantId, Page page){
        ModelAndView modelAndView = new ModelAndView("crowdfund/supportForRepresentList");
        SupportWithMember supportWithMember = new SupportWithMember();
        supportWithMember.setProjectId(projectId);
        supportWithMember.setMerchantId(merchantId);
        modelAndView.addAllObjects(supportBizService.listForRepresentCommonEvent(eventId, page, supportWithMember));
        modelAndView.addObject("isMultiple", false);
        return modelAndView;
    }

    /**
     * 导出众筹项目的支持
     * @param projectId 项目编号
     * @param response 响应参数
     * @return
     */
    @DataControl
    @ResponseBody
    @RequestMapping(value = "event/listForRepresentExport")
    public AjaxResult listEventForRepresentExport(@ControlParam(table = "zc_event", column = "create_by") String eventId,
                                                  @ControlParam(table = "activity", column = "member", isProjectId = true) String projectId, String merchantId){
        Project project = projectService.get(projectId);
        Member author = memberService.get(project.getAuthorId());
        String fileName = author.getRealname()+ "的众筹的支持人.xlsx";
        List<SupportWithMember> supportWithMemberList = supportBizService.listForProjectId(projectId, null, merchantId,null);
        try {
            ExportExcel exportExcel = new ExportExcel(fileName, SupportWithMember.class).setDataList(supportWithMemberList);
            String allPath = excelExportService.getExcelPath(fileName, "represent/support", exportExcel);
            return AjaxResult.success((Object) allPath);
        } catch (IOException e) {
            logger.error("导出支持人异常", e);
        }
        return AjaxResult.error("导出异常");
    }

    /**
     * 统计图表
     * @param projectId 项目编号
     * @return 输出视图
     */
    @ResponseBody
    @RequestMapping(value = "chart")
    public AjaxResult chart(String projectId){
        AjaxResult ajaxResult = new AjaxResult();
        SupportCountOutput supportCountOutput = supportBizService.chart(projectId);
        ajaxResult.setSuccess(true);
        ajaxResult.setData(supportCountOutput);
        return ajaxResult;
    }

    /**
     * 统计图表视图
     * @param projectId 项目编号
     * @return 输出视图
     */
    @RequestMapping(value = "chartView")
    public ModelAndView chartView(String projectId, String targetId, String eventId){
        ModelAndView modelAndView = new ModelAndView("crowdfund/supportChart");
        modelAndView.addObject("projectId", projectId);
        modelAndView.addObject("targetId", targetId);
        modelAndView.addObject("eventId", eventId);
        return modelAndView;
    }

    /**
     * 支持退款
     * @param id 支持编号
     * @return 交互数据
     */
    @ResponseBody
    @RequestMapping(value = "refund")
    @UserOperate(moduleName = "众筹项目-数据查看-众筹的列表-单个退款", behaviorType = BehaviorType.REFUND)
    public AjaxResult refund(String id){
        AjaxResult ajaxResult = new AjaxResult();
        try {
            Support support = supportService.get(id);
            boolean canRefund = projectService.isCanRefund(support.getProjectId());
            if(!canRefund){
                ajaxResult.setDescription("该众筹者已众筹成功，暂不支持退款");
                return ajaxResult;
            }

            supportBizService.sendRefund(id);
        } catch (BusinessException e) {
            ajaxResult.setDescription(e.getMessage());
            return ajaxResult;
        }
        ajaxResult.setSuccess(true);
        return ajaxResult;
    }

    /**
     * @param goalId
     * @return
     * @Author hzq
     * @Description //退款计划详情
     * @Date 17:26 2019/5/17
     **/
    @RequestMapping(value = "refundPlan")
    public ModelAndView refundPlan(String goalId) {
        ModelAndView mv = new ModelAndView("refundPlan/refundPlan");
        if (StringUtils.isBlank(goalId)) {
            return mv;
        }

        RefundPlan refundPlan = null;
        Integer refundFailure = null;
        Integer refundSuccess = null;
        Integer refundTotal = null;
        try {
            refundPlan = refundPlanService.getByGoalId(goalId);
            Support support = supportService.get(goalId);
            refundFailure = 0;
            refundSuccess = 0;
            refundTotal = 0;
            if (null == support) {
                Support support1 = new Support();
                support1.setProjectId(goalId);
                support1.setPayStatus(Constant.SUPPORT_PAY_STATUS_UNPAID);//待支付的状态
                //本次退款失败人数
                refundFailure = supportService.refundAllFailCount(goalId);
                //本次提交退款总人数，除了待支付的和退款成功的,都查出来
                List<Support> supportList = supportService.refundSubmitCount(support1);
                refundTotal = supportList.size();
                support1.setPayStatus(Constant.SUPPORT_PAY_STATUS_REFUND);
                //本次退款成功人数
                List<Support> supportList1 = supportService.refundSubmitCount(support1);
                refundSuccess = supportList1.size();
            } else {
                if(Constant.SUPPORT_PAY_STATUS_REFUND.equals(support.getPayStatus())){
                    refundSuccess = 1;
                }
                if(Constant.SUPPORT_PAY_STATUS_FAIL.equals(support.getPayStatus())){
                    refundFailure = 1;
                }
                refundTotal = 1;
            }
        } catch (Exception e) {
            logger.error("退款计划详情",e.getMessage());
        }
        mv.addObject("refundPlan", refundPlan);
        mv.addObject("refundFailure", refundFailure);
        mv.addObject("refundSuccess", refundSuccess);
        mv.addObject("refundTotal", refundTotal);
        return mv;
    }

    /**
     * @param goalId
     * @return
     * @Author hzq
     * @Description //取消退款
     * @Date 17:26 2019/5/17
     **/
    @RequestMapping(value = "cancelRefund")
    @ResponseBody
    public AjaxResult cancelRefund(String goalId) {
        AjaxResult ajaxResult = new AjaxResult();
        if (StringUtils.isBlank(goalId)) {
           return AjaxResult.error("goalId不能为空");
        }
        try {
            RefundPlan refundPlan = refundPlanService.getByGoalId(goalId);
            refundPlan.setStatus("0");//设置成无效状态
            refundPlan.setUpdateDate(new Date());
            refundPlanService.update(refundPlan);
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("取消退款异常",e);
            return AjaxResult.error("取消退款异常");
        }
    }
}
